package location

import (
	"strings"

	"device-admin/config/mysql"
	"device-admin/internal/models"

	"192.168.1.75/go-pkg/errorx"
	"192.168.1.75/go-pkg/helper"
)

type Floor struct{}

// FloorExits 判断楼层是否存在
func (Floor) FloorExists(floorID string) (models.Floor, error) {
	db := mysql.NewDB()
	// 判断楼层是否存在
	var floor models.Floor
	rowsAffected := db.Model(&models.Floor{}).Where("id = ?", floorID).Take(&floor).RowsAffected
	if rowsAffected <= 0 {
		return models.Floor{}, errorx.New("楼层不存在", -1)
	}
	return floor, nil
}

// List 楼层列表
func (Floor) List(locationID string, page, limit int, name string) ([]models.Floor, int64, error) {
	db := mysql.NewDB()
	tx := db.Model(&models.Floor{}).Where("location_id = ?", locationID)
	if name != "" {
		tx = tx.Where("name LIKE ?", "%"+name+"%")
	}
	// 校验location是否存在
	{
		var count int64
		tx.Count(&count)
	}
	// 查询记录
	{
		var count int64
		floors := []models.Floor{}
		tx.Count(&count)
		helper.Gorm{}.Paginate(tx, page, limit).Find(&floors)
		return floors, count, nil
	}
}

// Detial 楼层详情
func (Floor) Detail(id string) (models.Floor, error) {
	db := mysql.NewDB()

	var count int64
	var floor models.Floor
	count = db.Model(&models.Floor{}).Where("id = ?", id).Take(&floor).RowsAffected
	if count <= 0 {
		return models.Floor{}, errorx.New("楼层不存在", -1)
	}
	return floor, nil
}

// AddFloor 新增楼层
func (Floor) AddFloor(locationID string, name string, sort int) (string, error) {
	db := mysql.NewDB()
	// 校验location是否存在
	{
		var count int64
		db.Model(&models.Location{}).Where("id = ?", locationID).Count(&count)
		if count <= 0 {
			return "", errorx.New("位置不存在", -1)
		}
	}
	// 参数校验
	if name == "" {
		return "", errorx.New("楼层名称不能为空", -1)
	}
	// 新增楼层
	{
		var count int64
		var floor models.Floor
		floor.LocationID = locationID
		floor.Name = name
		floor.Sort = sort
		// 判断楼层是否已经存在
		db.Model(&models.Floor{}).
			Where("location_id = ?", locationID).
			Where("name = ?", name).
			Count(&count)
		if count > 0 {
			return "", errorx.New("楼层已存在", -1)
		}
		// 新增
		count = db.Model(&models.Floor{}).Create(&floor).RowsAffected
		if count <= 0 {
			return "", errorx.New("新增楼层失败", -1)
		} else {
			return floor.ID, nil
		}
	}
}

// EditFloor 编辑楼层
func (Floor) EditFloor(id string, name string, sort int) error {
	db := mysql.NewDB()

	// 校验楼层信息
	var floor models.Floor
	{
		count := db.Model(&models.Floor{}).Where("id = ?", id).Take(&floor).RowsAffected
		if count <= 0 {
			return errorx.New("楼层不存在", -1)
		}
	}
	// 判断楼层是否已经存在
	{
		var count int64
		db.Model(&models.Floor{}).
			Where("location_id = ?", floor.LocationID).
			Where("name = ?", name).
			Where("id <> ?", id).
			Count(&count)
		if count > 0 {
			return errorx.New("楼层已存在", -1)
		}
	}

	// 更新
	{
		rowsAffected := db.Model(&models.Floor{}).
			Where("id = ?", id).
			Updates(&models.Floor{
				Name: name,
				Sort: sort,
			}).RowsAffected
		if rowsAffected > 0 {
			return nil
		}
	}

	return errorx.New("楼层信息更新失败", -1)
}

// DeleteFloor 删除楼层
func (Floor) DeleteFloor(id string) error {
	db := mysql.NewDB()
	count := db.Model(&models.Floor{}).
		Where("id = ?", id).
		Delete(&models.Floor{}).RowsAffected
	if count <= 0 {
		return errorx.New("删除失败", -1)
	} else {
		return nil
	}
}

// AddBrand 新增楼层品牌
func (Floor) AddBrand(floorID string, brandID string) error {
	// 判断楼层是否是否存在
	floor := Floor{}
	if _, err := floor.FloorExists(floorID); err != nil {
		return err
	}

	brandIDArr := strings.Split(brandID, ",")
	for _, brandID := range brandIDArr {
		// 判断品牌是否存在
		brand := Brand{}
		if _, err := brand.BrandExists(brandID); err != nil {
			continue
		}
		// 判断楼层品牌是否已经存在
		var count int64
		mysql.NewDB().Model(&models.FloorBrand{}).
			Where("floor_id = ?", floorID).
			Where("brand_id = ?", brandID).
			Count(&count)
		if count > 0 {
			continue
		}
		// 添加楼层品牌
		var floorBrand models.FloorBrand
		{
			floorBrand.FloorID = floorID
			floorBrand.BrandID = brandID
			mysql.NewDB().Model(&models.FloorBrand{}).Create(&floorBrand)
		}
	}

	return nil
}

// EditBrand 编辑楼层品牌
func (Floor) EditBrand(bindID string, floorID string, brandID string, contactPhone string, shopNO string) error {
	// 判断楼层是否是否存在
	floor := Floor{}
	if _, err := floor.FloorExists(floorID); err != nil {
		return err
	}
	// 判断品牌是否存在
	brand := Brand{}
	if _, err := brand.BrandExists(brandID); err != nil {
		return err
	}
	// 判断楼层品牌是否已经存在
	var count int64
	mysql.NewDB().Model(&models.FloorBrand{}).Where("id = ?", bindID).Count(&count)
	if count <= 0 {
		return errorx.New("楼层品牌不存在", -1)
	}
	// 添加楼层品牌
	var floorBrand models.FloorBrand
	{
		floorBrand.FloorID = floorID
		floorBrand.ContactPhone = contactPhone
		floorBrand.ShopNO = shopNO
		rowsAffected := mysql.NewDB().Model(&models.FloorBrand{}).
			Where("id = ?", bindID).
			Select("floor_id", "contact_phone", "shop_no").
			Updates(&floorBrand).RowsAffected
		if rowsAffected <= 0 {
			return errorx.New("编辑楼层品牌失败", -1)
		}
	}
	return nil
}

// DeleteBrand 删除楼层品牌
func (Floor) DeleteBrand(floorID string, brandID string) error {
	// 判断楼层是否是否存在
	floor := Floor{}
	if _, err := floor.FloorExists(floorID); err != nil {
		return err
	}
	// 判断品牌是否存在
	brand := Brand{}
	if _, err := brand.BrandExists(brandID); err != nil {
		return err
	}
	// 先判断楼层品牌是否存在
	var count int64
	mysql.NewDB().
		Model(&models.FloorBrand{}).
		Where("floor_id = ?", floorID).
		Where("brand_id= ?", brandID).
		Count(&count)
	if count <= 0 {
		return errorx.New("楼层品牌不存在", -1)
	}
	// 删除
	rowsAffected := mysql.NewDB().
		Model(&models.FloorBrand{}).
		Where("floor_id = ?", floorID).
		Where("brand_id= ?", brandID).
		Delete(&models.FloorBrand{}).RowsAffected
	if rowsAffected <= 0 {
		return errorx.New("删除楼层品牌失败", -1)
	}

	return nil
}

// SetBrandSort 设置楼层品牌推荐
func (Floor) BrandRecommend(floorID string, brandID string, recommended int, sort int) error {
	// 判断楼层品牌是否已经存在
	{
		var count int64
		mysql.NewDB().Model(&models.FloorBrand{}).Where(models.FloorBrand{
			FloorID: floorID,
			BrandID: brandID,
		}).Count(&count)
		if count <= 0 {
			return errorx.New("楼层品牌不存在", -1)
		}
	}

	// 更新
	{
		rowsAffected := mysql.NewDB().Model(&models.FloorBrand{}).
			Where("floor_id= ?", floorID).
			Where("brand_id = ?", brandID).
			Updates(map[string]interface{}{
				"recommended":      recommended,
				"recommended_sort": sort,
			}).RowsAffected
		if rowsAffected <= 0 {
			return errorx.New("设置推荐失败", -1)
		}
	}

	return nil
}

// BrandSearchRecommend 品牌搜索推荐
func (Floor) BrandSearchRecommend(floorID string, brandID string, recommended int, sort int) error {
	// 判断楼层品牌是否已经存在
	{
		var count int64
		mysql.NewDB().Model(&models.FloorBrand{}).
			Where("floor_id= ?", floorID).
			Where("brand_id = ?", brandID).
			Count(&count)
		if count <= 0 {
			return errorx.New("楼层品牌不存在", -1)
		}
	}

	// 更新
	{
		rowsAffected := mysql.NewDB().Model(&models.FloorBrand{}).
			Where("floor_id= ?", floorID).
			Where("brand_id = ?", brandID).
			Updates(map[string]interface{}{
				"search_recommended":      recommended,
				"search_recommended_sort": sort,
			}).RowsAffected
		if rowsAffected <= 0 {
			return errorx.New("设置搜索推荐失败", -1)
		}
	}

	return nil
}

// BrandInfo 品牌信息
type BrandInfo struct {
	BindID                string `json:"bind_id" gorm:"bind_id"`
	Name                  string `json:"name" gorm:"column:name"`
	Logo                  string `json:"logo" gorm:"column:logo"`
	Desc                  string `json:"desc" gorm:"column:desc"`
	ContactPhone          string `json:"contact_phone" gorm:"column:contact_phone"`
	ShopNO                string `json:"shop_no" gorm:"column:shop_no"`
	BrandID               string `json:"brand_id" gorm:"column:brand_id"`
	FloorID               string `json:"floor_id" gorm:"column:floor_id"`
	FloorName             string `json:"floor_name" gorm:"column:floor_name"`
	PositionID            string `json:"position_id" gorm:"column:position_id"`
	PositionName          string `json:"position_name" gorm:"column:position_name"`
	Recommended           int    `json:"recommended" gorm:"column:recommended"`
	SearchRecommended     int    `json:"search_recommended" gorm:"column:search_recommended"`
	RecommendedSort       int    `json:"recommended_sort" gorm:"column:recommended_sort"`
	SearchRecommendedSort int    `json:"search_recommended_sort" gorm:"column:search_recommended_sort"`
}

// 获取推荐品牌
func (Floor) GetRecommendedBrand(robotID string, locationID string, recommended int) ([]BrandInfo, error) {
	db := mysql.NewDB()
	if robotID != "" {
		// 获取设备绑定的楼层信息
		var floorDevice models.FloorDevice
		rowsAffected := db.Model(&models.FloorDevice{}).
			Where("robot_id = ?", robotID).
			Take(&floorDevice).RowsAffected
		if rowsAffected <= 0 {
			return nil, errorx.New("设备未绑定楼层信息", -1)
		}

		// 获取楼层的位置
		var floor models.Floor
		rowsAffected = db.Model(&models.Floor{}).
			Where("id = ?", floorDevice.FloorID).
			Take(&floor).RowsAffected
		if rowsAffected <= 0 {
			return nil, errorx.New("楼层不存在", -1)
		}
		locationID = floor.LocationID
	}
	// 获取品牌列表
	{
		var brands []BrandInfo
		tx := db.Model(&models.FloorBrand{}).
			Joins("JOIN floor ON floor.id = floor_brand.floor_id").
			Joins("JOIN brand ON brand.id = floor_brand.brand_id").
			Select(
				"floor_brand.id as bind_id",
				"brand.name as `name`",
				"brand.logo as `logo`",
				"brand.desc as `desc`",
				"floor.name as floor_name",
				"floor_brand.contact_phone",
				"floor_brand.shop_no",
				"brand.id as brand_id",
				"floor_brand.floor_id",
				"floor_brand.position_id",
				"floor_brand.recommended",
				"floor_brand.recommended_sort",
				"floor_brand.search_recommended",
				"floor_brand.search_recommended_sort",
			).
			Where("floor.location_id = ?", locationID)
		if recommended == 0 {
			tx = tx.Where("floor_brand.recommended = ?", 0)
		} else if recommended > 0 {
			tx = tx.Where("floor_brand.recommended = ?", 1)
		}
		tx.Order("floor_brand.recommended_sort").Find(&brands)
		return brands, nil
	}
}

func (Floor) GetSearchRecommendedBrand(robotID string, locationID string, searchRecommended int) ([]BrandInfo, error) {
	db := mysql.NewDB()
	if robotID != "" {
		// 获取设备绑定的楼层信息
		var floorDevice models.FloorDevice
		rowsAffected := db.Model(&models.FloorDevice{}).Where(models.FloorDevice{
			RobotID: robotID,
		}).Take(&floorDevice).RowsAffected
		if rowsAffected <= 0 {
			return nil, errorx.New("设备未绑定楼层信息", -1)
		}

		// 获取楼层的位置
		var floor models.Floor
		rowsAffected = db.Model(&models.Floor{}).
			Where("id = ?", floorDevice.FloorID).
			Take(&floor).RowsAffected
		if rowsAffected <= 0 {
			return nil, errorx.New("楼层不存在", -1)
		}
		locationID = floor.LocationID
	}
	// 获取品牌列表
	{
		var brands []BrandInfo
		tx := db.Model(&models.FloorBrand{}).
			Joins("JOIN floor ON floor.id = floor_brand.floor_id").
			Joins("JOIN brand ON brand.id = floor_brand.brand_id").
			Select(
				"floor_brand.id as bind_id",
				"brand.name as `name`",
				"brand.logo as `logo`",
				"brand.desc as `desc`",
				"floor.name as floor_name",
				"floor_brand.contact_phone",
				"floor_brand.shop_no",
				"brand.id as brand_id",
				"floor_brand.floor_id",
				"floor_brand.position_id",
				"floor_brand.recommended",
				"floor_brand.recommended_sort",
				"floor_brand.search_recommended",
				"floor_brand.search_recommended_sort",
			).
			Where("floor.location_id = ?", locationID)

		if searchRecommended == 0 {
			tx = tx.Where("floor_brand.search_recommended = ?", 0)
		} else if searchRecommended > 0 {
			tx = tx.Where("floor_brand.search_recommended = ?", 1)
		}
		tx.Order("search_recommended_sort").Find(&brands)
		return brands, nil
	}
}
